package com.wtzz.police.base.service.base;

import com.wtzz.police.base.entity.AbstractIdEntity;
import com.wtzz.police.base.model.enums.WtzzResponse;
import com.wtzz.police.base.model.exception.WtzzRuntimeException;
import com.wtzz.police.base.repository.base.BaseRepository;
import com.wtzz.police.base.util.component.MapperWrapper;
import io.swagger.annotations.ApiModel;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.IterableUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.support.JpaRepositoryImplementation;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import java.io.Serializable;
import java.util.List;
import java.util.Optional;

/**
 * CrudService基类实现
 */
@Slf4j
public abstract class BaseCurdServiceImpl<T, ID extends Serializable> implements BaseCurdService<T, ID> {

    @Autowired
    protected MapperWrapper mapper;
    @PersistenceContext
    protected EntityManager em;

    protected abstract BaseRepository<T, ID> getRepository();

    @Override
    public void add(Object data) {
        T t = mapper.map(data, getRepository().getEntityClass());
        getRepository().save(t);
        log.info("新增{}", getRepository().getEntityDesc());
    }

    @Override
    public void delete(ID id) {
        getRepository().delete(getRepository().findByIdOrThrow(id));
        log.info("删除{}, 其ID为:{}", getRepository().getEntityDesc(), id);
    }

    @Override
    public void deleteAll(Iterable<ID> ids) {
        getRepository().deleteAll(getRepository().findAllById(ids));
        log.info("批量删除{}, 其ID为:{}", getRepository().getEntityDesc(), IterableUtils.toString(ids));
    }

    @Override
    public void logicalDelete(ID id) {
        T t = getRepository().findByIdOrThrow(id);
        if (t instanceof AbstractIdEntity) {
            ((AbstractIdEntity) t).setDeleted(true);
        } else {
            throw new WtzzRuntimeException(getRepository().getEntityDesc() + "不支持逻辑删除");
        }
        log.info("逻辑删除{}", getRepository().getEntityDesc());
    }

    @Override
    public void logicalDeleteAllInBatch(Iterable<ID> ids) {
        Iterable<T> entities = getRepository().findAllById(ids);
        if (!IterableUtils.isEmpty(entities)) {
            if (!(IterableUtils.first(entities) instanceof AbstractIdEntity)) {
                throw new WtzzRuntimeException(getRepository().getEntityDesc() + "不支持逻辑删除");
            }
            for (T entity : entities) {
                ((AbstractIdEntity) entity).setDeleted(true);
            }
        }
        log.info("批量逻辑删除{}, 其ID为:{}", getRepository().getEntityDesc(), IterableUtils.toString(ids));
    }

    @Override
    public void update(ID id, Object data) {
        T t = getRepository().findByIdOrThrow(id);
        mapper.map(t, data);
        getRepository().save(t);
        log.info("更新{}, 其ID为:{}", getRepository().getEntityDesc(), id);
    }

    protected T find(ID id) {
        return getRepository().findByIdOrThrow(id);
    }

    protected T findNotDeleted(ID id) {
        return getRepository().findNotLogicalDeleted(id);
    }

    protected List<T> listAll() {
        return getRepository().findAll();
    }

    protected Page<T> list(Pageable page) {
        return getRepository().findAll(page);
    }
}
